package com.td.module.member.service.appMemberUser;

import cn.hutool.core.util.StrUtil;
import com.google.common.annotations.VisibleForTesting;
import com.td.framework.common.enums.CommonStatusEnum;
import com.td.framework.common.pojo.PageResult;
import com.td.module.farmer.dal.dataobject.management.ManagementDO;
import com.td.module.farmer.dal.mysql.management.ManagementMapper;
import com.td.module.member.controller.admin.appMemberUser.vo.AppMemberUserCreateReqVO;
import com.td.module.member.controller.admin.appMemberUser.vo.AppMemberUserExportReqVO;
import com.td.module.member.controller.admin.appMemberUser.vo.AppMemberUserPageReqVO;
import com.td.module.member.controller.admin.appMemberUser.vo.AppMemberUserUpdateReqVO;
import com.td.module.member.convert.appMemberUser.AppMemberUserConvert;
import com.td.module.member.dal.dataobject.appMemberUser.AppMemberUserDO;
import com.td.module.member.dal.mysql.appMemberUser.AppMemberUserMapper;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static com.td.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.td.framework.common.util.servlet.ServletUtils.getClientIP;
import static com.td.module.member.enums.ErrorCodeConstants.APP_MEMBER_MOBILE_EXISTS;
import static com.td.module.member.enums.ErrorCodeConstants.APP_MEMBER_USER_NOT_EXISTS;

/**
 * app用户 Service 实现类
 *
 * @author 王翔翔
 */
@Service
@Validated
public class AppMemberUserServiceImpl implements AppMemberUserService {

    @Resource
    private AppMemberUserMapper appMemberUserMapper;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private ManagementMapper managementMapper;

    //校验用户是否存在
    private void checkCreateOrUpdate(Long id, String mobile) {
        // 校验用户存在
        this.checkUserExists(id);
        // 校验手机号唯一
        this.checkMobileUnique(id, mobile);
    }

    @VisibleForTesting
    public void checkUserExists(Long id) {
        if (id == null) {
            return;
        }
        AppMemberUserDO appMemberUserDO = appMemberUserMapper.selectById(id);
        if (StrUtil.isEmptyIfStr(appMemberUserDO)) {
            throw exception(APP_MEMBER_USER_NOT_EXISTS);
        }
    }

    @VisibleForTesting
    public void checkMobileUnique(Long id, String mobile) {
        if (StrUtil.isBlank(mobile)) {
            return;
        }
        AppMemberUserDO appMemberUserDO = appMemberUserMapper.selectByMobile(mobile);
        if (appMemberUserDO == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(APP_MEMBER_MOBILE_EXISTS);
        }
        if (!appMemberUserDO.getId().equals(id)) {
            throw exception(APP_MEMBER_MOBILE_EXISTS);
        }
    }

    @Override
    public Long createAppMemberUser(AppMemberUserCreateReqVO createReqVO) {
        //校验用户是否存在
        this.checkCreateOrUpdate(null, createReqVO.getMobile());
        // 插入
        AppMemberUserDO appMemberUser = AppMemberUserConvert.INSTANCE.convert(createReqVO);
        appMemberUser.setStatus(CommonStatusEnum.ENABLE.getStatus()); //默认用户开启状态
        appMemberUser.setPassword(passwordEncoder.encode(createReqVO.getPassword()));
        appMemberUser.setRegisterIp(getClientIP());
        appMemberUser.setIsAuth(2);//默认用户没有实名

        //关联大户ID
        ManagementDO managementByMobile = managementMapper.selectByMobile(appMemberUser.getMobile());
        if (Objects.nonNull(managementByMobile)) {
            appMemberUser.setFarmerId(managementByMobile.getId());
        }

        appMemberUserMapper.insert(appMemberUser);
        // 返回
        return appMemberUser.getId();
    }

    @Override
    public void updateAppMemberUser(AppMemberUserUpdateReqVO updateReqVO) {
        // 校验存在
        this.checkUserExists(updateReqVO.getId());
        // 更新
        AppMemberUserDO updateObj = AppMemberUserConvert.INSTANCE.convert(updateReqVO);
        appMemberUserMapper.updateById(updateObj);
    }

    @Override
    public void deleteAppMemberUser(Long id) {
        // 校验存在
        this.checkUserExists(id);
        // 删除
        appMemberUserMapper.deleteById(id);
    }

    @Override
    public AppMemberUserDO getAppMemberUser(Long id) {
        return appMemberUserMapper.selectById(id);
    }

    @Override
    public List<AppMemberUserDO> getAppMemberUserList(Collection<Long> ids) {
        return appMemberUserMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<AppMemberUserDO> getAppMemberUserPage(AppMemberUserPageReqVO pageReqVO) {
        return appMemberUserMapper.selectPage(pageReqVO);
    }

    @Override
    public List<AppMemberUserDO> getAppMemberUserList(AppMemberUserExportReqVO exportReqVO) {
        return appMemberUserMapper.selectList(exportReqVO);
    }

    @Override
    public void updateAppMemberUserPassword(Long id, String password) {
        // 校验用户是否存在
        this.checkUserExists(id);
        // 更新密码
        AppMemberUserDO appMemberUserDO = new AppMemberUserDO();
        appMemberUserDO.setId(id);
        appMemberUserDO.setPassword(passwordEncoder.encode(password));//加密密码
        appMemberUserMapper.updateById(appMemberUserDO);
    }

    @Override
    public void updateAppMemberUserStatus(Long id, Integer status) {
        // 校验用户是否存在
        this.checkUserExists(id);
        // 更新状态
        AppMemberUserDO appMemberUserDO = new AppMemberUserDO();
        appMemberUserDO.setId(id);
        appMemberUserDO.setStatus(status);
        appMemberUserMapper.updateById(appMemberUserDO);
    }

    @Override
    public Boolean associationContract(Long id) {
        AppMemberUserDO appMemberUserDO = appMemberUserMapper.selectById(id);
        if (Objects.nonNull(appMemberUserDO) && Objects.isNull(appMemberUserDO.getFarmerId())) {
            ManagementDO managementByMobile = managementMapper.selectByMobile(appMemberUserDO.getMobile());
            if (Objects.nonNull(managementByMobile)) {
                appMemberUserDO.setFarmerId(managementByMobile.getId());
                appMemberUserDO.setNickname(managementByMobile.getName());
                appMemberUserDO.setIsAuth(1);
                appMemberUserMapper.updateById(appMemberUserDO);
                return true;
            }
        }
        return false;
    }

}
